home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / pyxmpp / stanzaprocessor.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  9KB  |  331 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __revision__ = '$Id: stanzaprocessor.py 668 2007-01-05 16:24:08Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import libxml2
  7. import logging
  8. import threading
  9. from pyxmpp.expdict import ExpiringDictionary
  10. from pyxmpp.exceptions import ProtocolError, BadRequestProtocolError, FeatureNotImplementedProtocolError
  11. from pyxmpp.stanza import Stanza
  12.  
  13. class StanzaProcessor:
  14.     
  15.     def __init__(self):
  16.         self.me = None
  17.         self.peer = None
  18.         self.initiator = None
  19.         self.peer_authenticated = False
  20.         self.process_all_stanzas = True
  21.         self._iq_response_handlers = ExpiringDictionary()
  22.         self._iq_get_handlers = { }
  23.         self._iq_set_handlers = { }
  24.         self._message_handlers = []
  25.         self._presence_handlers = []
  26.         self._StanzaProcessor__logger = logging.getLogger('pyxmpp.Stream')
  27.         self.lock = threading.RLock()
  28.  
  29.     
  30.     def process_response(self, response):
  31.         if response is None or response is False:
  32.             return False
  33.         
  34.         if isinstance(response, Stanza):
  35.             self.send(response)
  36.             return True
  37.         
  38.         
  39.         try:
  40.             response = iter(response)
  41.         except TypeError:
  42.             return bool(response)
  43.  
  44.         for stanza in response:
  45.             if isinstance(stanza, Stanza):
  46.                 self.send(stanza)
  47.                 continue
  48.         
  49.         return True
  50.  
  51.     
  52.     def process_iq(self, stanza):
  53.         sid = stanza.get_id()
  54.         fr = stanza.get_from()
  55.         typ = stanza.get_type()
  56.         if typ in ('result', 'error'):
  57.             if fr:
  58.                 ufr = fr.as_unicode()
  59.             else:
  60.                 ufr = None
  61.             if self._iq_response_handlers.has_key((sid, ufr)):
  62.                 key = (sid, ufr)
  63.             elif (fr == self.peer and fr == self.me or fr == self.me.bare()) and self._iq_response_handlers.has_key((sid, None)):
  64.                 key = (sid, None)
  65.             else:
  66.                 self._StanzaProcessor__logger.warning('ignoring stanza from %r', fr)
  67.                 self._StanzaProcessor__logger.warning('I am %r', self.me)
  68.                 self._StanzaProcessor__logger.warning(self._iq_response_handlers.keys())
  69.                 return False
  70.             (res_handler, err_handler) = self._iq_response_handlers[key]
  71.             if stanza.get_type() == 'result':
  72.                 response = res_handler(stanza)
  73.             else:
  74.                 response = err_handler(stanza)
  75.             
  76.             try:
  77.                 del self._iq_response_handlers[key]
  78.                 self.process_response(response)
  79.             except KeyError:
  80.                 pass
  81.  
  82.             return True
  83.         
  84.         q = stanza.get_query()
  85.         if not q:
  86.             raise BadRequestProtocolError, 'Stanza with no child element'
  87.         
  88.         el = q.name
  89.         ns = q.ns().getContent()
  90.         if typ == 'get':
  91.             if self._iq_get_handlers.has_key((el, ns)):
  92.                 response = self._iq_get_handlers[(el, ns)](stanza)
  93.                 self.process_response(response)
  94.                 return True
  95.             else:
  96.                 raise FeatureNotImplementedProtocolError, 'Not implemented'
  97.         elif typ == 'set':
  98.             if self._iq_set_handlers.has_key((el, ns)):
  99.                 response = self._iq_set_handlers[(el, ns)](stanza)
  100.                 self.process_response(response)
  101.                 return True
  102.             else:
  103.                 raise FeatureNotImplementedProtocolError, 'Not implemented'
  104.         else:
  105.             raise BadRequestProtocolError, 'Unknown IQ stanza type'
  106.  
  107.     
  108.     def __try_handlers(self, handler_list, typ, stanza):
  109.         namespaces = []
  110.         if stanza.xmlnode.children:
  111.             c = stanza.xmlnode.children
  112.             while c:
  113.                 
  114.                 try:
  115.                     ns = c.ns()
  116.                 except libxml2.treeError:
  117.                     ns = None
  118.  
  119.                 if ns is None:
  120.                     c = c.next
  121.                     continue
  122.                 
  123.                 ns_uri = ns.getContent()
  124.                 if ns_uri not in namespaces:
  125.                     namespaces.append(ns_uri)
  126.                 
  127.                 c = c.next
  128.         
  129.         for handler_entry in handler_list:
  130.             t = handler_entry[1]
  131.             ns = handler_entry[2]
  132.             handler = handler_entry[3]
  133.             if t != typ:
  134.                 continue
  135.             
  136.             if ns is not None and ns not in namespaces:
  137.                 continue
  138.             
  139.             response = handler(stanza)
  140.             if self.process_response(response):
  141.                 return True
  142.                 continue
  143.         
  144.         return False
  145.  
  146.     
  147.     def process_message(self, stanza):
  148.         if not (self.initiator) and not (self.peer_authenticated):
  149.             self._StanzaProcessor__logger.debug('Ignoring message - peer not authenticated yet')
  150.             return True
  151.         
  152.         typ = stanza.get_type()
  153.         if self._StanzaProcessor__try_handlers(self._message_handlers, typ, stanza):
  154.             return True
  155.         
  156.         if typ != 'error':
  157.             return self._StanzaProcessor__try_handlers(self._message_handlers, 'normal', stanza)
  158.         
  159.         return False
  160.  
  161.     
  162.     def process_presence(self, stanza):
  163.         if not (self.initiator) and not (self.peer_authenticated):
  164.             self._StanzaProcessor__logger.debug('Ignoring presence - peer not authenticated yet')
  165.             return True
  166.         
  167.         typ = stanza.get_type()
  168.         if not typ:
  169.             typ = 'available'
  170.         
  171.         return self._StanzaProcessor__try_handlers(self._presence_handlers, typ, stanza)
  172.  
  173.     
  174.     def route_stanza(self, stanza):
  175.         if stanza.get_type() not in ('error', 'result'):
  176.             r = stanza.make_error_response('recipient-unavailable')
  177.             self.send(r)
  178.         
  179.         return True
  180.  
  181.     
  182.     def process_stanza(self, stanza):
  183.         self.fix_in_stanza(stanza)
  184.         to = stanza.get_to()
  185.         if not (self.process_all_stanzas) and to and to != self.me and to.bare() != self.me.bare():
  186.             return self.route_stanza(stanza)
  187.         
  188.         
  189.         try:
  190.             if stanza.stanza_type == 'iq':
  191.                 if self.process_iq(stanza):
  192.                     return True
  193.                 
  194.             elif stanza.stanza_type == 'message':
  195.                 if self.process_message(stanza):
  196.                     return True
  197.                 
  198.             elif stanza.stanza_type == 'presence':
  199.                 if self.process_presence(stanza):
  200.                     return True
  201.                 
  202.         except ProtocolError:
  203.             e = None
  204.             typ = stanza.get_type()
  205.             if typ != 'error':
  206.                 pass
  207.             None if typ != 'result' or stanza.stanza_type != 'iq' else stanza.stanza_type != 'iq'
  208.             e.log_ignored()
  209.  
  210.         self._StanzaProcessor__logger.debug('Unhandled %r stanza: %r' % (stanza.stanza_type, stanza.serialize()))
  211.         return False
  212.  
  213.     
  214.     def check_to(self, to):
  215.         if to != self.me:
  216.             return None
  217.         
  218.         return to
  219.  
  220.     
  221.     def set_response_handlers(self, iq, res_handler, err_handler, timeout_handler = None, timeout = 300):
  222.         self.lock.acquire()
  223.         
  224.         try:
  225.             self._set_response_handlers(iq, res_handler, err_handler, timeout_handler, timeout)
  226.         finally:
  227.             self.lock.release()
  228.  
  229.  
  230.     
  231.     def _set_response_handlers(self, iq, res_handler, err_handler, timeout_handler = None, timeout = 300):
  232.         self.fix_out_stanza(iq)
  233.         to = iq.get_to()
  234.         if to:
  235.             to = to.as_unicode()
  236.         
  237.         if timeout_handler:
  238.             self._iq_response_handlers.set_item((iq.get_id(), to), (res_handler, err_handler), timeout, timeout_handler)
  239.         else:
  240.             self._iq_response_handlers.set_item((iq.get_id(), to), (res_handler, err_handler), timeout)
  241.  
  242.     
  243.     def set_iq_get_handler(self, element, namespace, handler):
  244.         self.lock.acquire()
  245.         
  246.         try:
  247.             self._iq_get_handlers[(element, namespace)] = handler
  248.         finally:
  249.             self.lock.release()
  250.  
  251.  
  252.     
  253.     def unset_iq_get_handler(self, element, namespace):
  254.         self.lock.acquire()
  255.         
  256.         try:
  257.             if self._iq_get_handlers.has_key((element, namespace)):
  258.                 del self._iq_get_handlers[(element, namespace)]
  259.         finally:
  260.             self.lock.release()
  261.  
  262.  
  263.     
  264.     def set_iq_set_handler(self, element, namespace, handler):
  265.         self.lock.acquire()
  266.         
  267.         try:
  268.             self._iq_set_handlers[(element, namespace)] = handler
  269.         finally:
  270.             self.lock.release()
  271.  
  272.  
  273.     
  274.     def unset_iq_set_handler(self, element, namespace):
  275.         self.lock.acquire()
  276.         
  277.         try:
  278.             if self._iq_set_handlers.has_key((element, namespace)):
  279.                 del self._iq_set_handlers[(element, namespace)]
  280.         finally:
  281.             self.lock.release()
  282.  
  283.  
  284.     
  285.     def __add_handler(self, handler_list, typ, namespace, priority, handler):
  286.         if priority < 0 or priority > 100:
  287.             raise ValueError, 'Bad handler priority (must be in 0:100)'
  288.         
  289.         handler_list.append((priority, typ, namespace, handler))
  290.         handler_list.sort()
  291.  
  292.     
  293.     def set_message_handler(self, typ, handler, namespace = None, priority = 100):
  294.         self.lock.acquire()
  295.         
  296.         try:
  297.             if not typ:
  298.                 typ == 'normal'
  299.             
  300.             self._StanzaProcessor__add_handler(self._message_handlers, typ, namespace, priority, handler)
  301.         finally:
  302.             self.lock.release()
  303.  
  304.  
  305.     
  306.     def set_presence_handler(self, typ, handler, namespace = None, priority = 100):
  307.         self.lock.acquire()
  308.         
  309.         try:
  310.             if not typ:
  311.                 typ = 'available'
  312.             
  313.             self._StanzaProcessor__add_handler(self._presence_handlers, typ, namespace, priority, handler)
  314.         finally:
  315.             self.lock.release()
  316.  
  317.  
  318.     
  319.     def fix_in_stanza(self, stanza):
  320.         pass
  321.  
  322.     
  323.     def fix_out_stanza(self, stanza):
  324.         pass
  325.  
  326.     
  327.     def send(self, stanza):
  328.         raise NotImplementedError, 'This method must be overriden in derived classes.'
  329.  
  330.  
  331.